#include "dataanalysis.h"
#include "ui_dataanalysis.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QDateTimeAxis>
#include <QValueAxis>
#include <QLineSeries>
#include <QBarSeries>
#include <QBarSet>
#include <QChartView>
#include <QPrinter>
#include <QPainter>
#include <QPdfWriter>
#include <QDebug>

DataAnalysis::DataAnalysis(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DataAnalysis),
    m_temperatureChart(new QChart()),
    m_humidityChart(new QChart()),
    m_alertChart(new QChart()),
    m_currentDeviceId(-1)
{
    ui->setupUi(this);

    // 初始化数据库管理器
    dbManager = DatabaseManager::instance();

    // 初始化时间范围
    m_startTime = QDateTime::currentDateTime().addDays(-7);
    m_endTime = QDateTime::currentDateTime();
    ui->startDateTimeEdit->setDateTime(m_startTime);
    ui->endDateTimeEdit->setDateTime(m_endTime);

    // 设置图表
    m_temperatureChart = new QChart();
    m_temperatureChart->setTitle("请选择设备查看温度数据");

    m_humidityChart = new QChart();
    m_humidityChart->setTitle("请选择设备查看湿度数据");

    m_alertChart = new QChart();
    m_alertChart->setTitle("请选择设备查看告警数据");

    // 设置到视图
    ui->temperatureChartView->setChart(m_temperatureChart);
    ui->humidityChartView->setChart(m_humidityChart);
    ui->alertChartView->setChart(m_alertChart);
    setupCharts();

    // 加载设备列表
    loadDeviceList();

    // 设置信号槽连接
    setupConnections();
}

DataAnalysis::~DataAnalysis()
{
    delete ui;
    delete m_temperatureChart;
    delete m_humidityChart;
    delete m_alertChart;
}

void DataAnalysis::setupCharts()
{
    // 温度图表设置
    m_temperatureChart->setTitle("温度趋势分析");
    m_temperatureChart->legend()->setVisible(true);
    m_temperatureChart->setAnimationOptions(QChart::AllAnimations);
    ui->temperatureChartView->setChart(m_temperatureChart);
    ui->temperatureChartView->setRenderHint(QPainter::Antialiasing);

    // 湿度图表设置
    m_humidityChart->setTitle("湿度趋势分析");
    m_humidityChart->legend()->setVisible(true);
    m_humidityChart->setAnimationOptions(QChart::AllAnimations);
    ui->humidityChartView->setChart(m_humidityChart);
    ui->humidityChartView->setRenderHint(QPainter::Antialiasing);

    // 告警图表设置
    m_alertChart->setTitle("告警统计");
    m_alertChart->legend()->setVisible(true);
    m_alertChart->setAnimationOptions(QChart::AllAnimations);
    ui->alertChartView->setChart(m_alertChart);
    ui->alertChartView->setRenderHint(QPainter::Antialiasing);
}

void DataAnalysis::setupConnections()
{
    connect(ui->deviceComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &DataAnalysis::onDeviceSelectionChanged);
    connect(ui->startDateTimeEdit, &QDateTimeEdit::dateTimeChanged,
            this, &DataAnalysis::onTimeRangeChanged);
    connect(ui->endDateTimeEdit, &QDateTimeEdit::dateTimeChanged,
            this, &DataAnalysis::onTimeRangeChanged);
    connect(ui->exportButton, &QPushButton::clicked,
            this, &DataAnalysis::exportChart);
    connect(ui->analyzeButton, &QPushButton::clicked,
            this, &DataAnalysis::onAnalyzeButtonClicked);
}

void DataAnalysis::loadDeviceList()
{
    ui->deviceComboBox->clear();
    ui->deviceComboBox->addItem("所有设备", -1);  // 第一个选项为"所有设备"

    QString sql = "SELECT DISTINCT device_id FROM data ORDER BY device_id";
    QString response = dbManager->sendRequest(sql);

    if (response.startsWith("Error:")) {
        QMessageBox::critical(this, "错误", "获取设备列表失败: " + response.mid(6));
        return;
    }

    QStringList rows = response.split("\n", QString::SkipEmptyParts);
    foreach (const QString &row, rows) {
        QStringList cols = row.split(" | ", QString::SkipEmptyParts);
        if (cols.size() >= 1) {
            int deviceId = cols[0].toInt();
            ui->deviceComboBox->addItem(QString("设备 %1").arg(deviceId), deviceId);
        }
    }

    // 默认选择"所有设备"
    ui->deviceComboBox->setCurrentIndex(0);
}

void DataAnalysis::onDeviceSelectionChanged(int index)
{
    if (index < 0) return;

    m_currentDeviceId = ui->deviceComboBox->itemData(index).toInt();

    // 只有当选择了具体设备(不是"所有设备")时才更新图表
    if (m_currentDeviceId != -1) {
        updateCharts();
    } else {
        // 清除所有图表数据
        clearAllCharts();
    }
}

void DataAnalysis::clearAllCharts()
{
    // 清除温度图表
    m_temperatureChart->removeAllSeries();
    foreach(QAbstractAxis* axis, m_temperatureChart->axes()) {
        m_temperatureChart->removeAxis(axis);
        delete axis;
    }
    m_temperatureChart->setTitle("温度趋势分析");

    // 清除湿度图表
    m_humidityChart->removeAllSeries();
    foreach(QAbstractAxis* axis, m_humidityChart->axes()) {
        m_humidityChart->removeAxis(axis);
        delete axis;
    }
    m_humidityChart->setTitle("湿度趋势分析");

    // 清除告警图表
    m_alertChart->removeAllSeries();
    foreach(QAbstractAxis* axis, m_alertChart->axes()) {
        m_alertChart->removeAxis(axis);
        delete axis;
    }
    m_alertChart->setTitle("告警统计");

    // 清空分析结果
    ui->analysisResultLabel->setText("请选择设备以查看数据分析");
}

void DataAnalysis::onTimeRangeChanged()
{
    m_startTime = ui->startDateTimeEdit->dateTime();
    m_endTime = ui->endDateTimeEdit->dateTime();

    if (m_startTime > m_endTime) {
        QMessageBox::warning(this, "警告", "开始时间不能晚于结束时间");
        return;
    }

    // 只有当选择了具体设备时才更新图表
    if (m_currentDeviceId != -1) {
        updateCharts();
    }
}

void DataAnalysis::updateCharts()
{
    loadTemperatureData();
    loadHumidityData();
    loadAlertData();
}

QVector<QPair<QDateTime, double>> DataAnalysis::fetchData(const QString& field)
{
    QVector<QPair<QDateTime, double>> data;

    QString sql = QString("SELECT timestamp, %1 FROM data WHERE timestamp BETWEEN '%2' AND '%3'")
                 .arg(field)
                 .arg(m_startTime.toString(Qt::ISODate))
                 .arg(m_endTime.toString(Qt::ISODate));

    if (m_currentDeviceId != -1) {
        sql += QString(" AND device_id = %1").arg(m_currentDeviceId);
    }
    sql += " ORDER BY timestamp";

    QString response = dbManager->sendRequest(sql);
    if (response.startsWith("Error:")) {
        qDebug() << "获取数据失败:" << response;
        return data;
    }

    QStringList rows = response.split("\n", QString::SkipEmptyParts);
    foreach (const QString &row, rows) {
        QStringList cols = row.split(" | ", QString::SkipEmptyParts);
        if (cols.size() >= 2) {
            QDateTime timestamp = QDateTime::fromString(cols[0], Qt::ISODate);
            double value = cols[1].toDouble();
            data.append(qMakePair(timestamp, value));
        }
    }

    return data;
}

void DataAnalysis::loadTemperatureData()
{
    m_temperatureChart->removeAllSeries();
    foreach(QAbstractAxis* axis, m_temperatureChart->axes()) {
        m_temperatureChart->removeAxis(axis);
        delete axis;
    }

    auto temperatureData = fetchData("temperature");
    QLineSeries *series = new QLineSeries();
    series->setName(m_currentDeviceId == -1 ? "平均温度" : QString("设备 %1 温度").arg(m_currentDeviceId));

    for (const auto& point : temperatureData) {
        series->append(point.first.toMSecsSinceEpoch(), point.second);
    }

    m_temperatureChart->addSeries(series);

    // 设置X轴(时间轴)
    QDateTimeAxis *axisX = new QDateTimeAxis;
    axisX->setFormat("MM-dd hh:mm");
    axisX->setTitleText("时间");
    m_temperatureChart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    // 设置Y轴(温度值)
    QValueAxis *axisY = new QValueAxis;
    axisY->setLabelFormat("%.1f");
    axisY->setTitleText("温度(℃)");
    m_temperatureChart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
}

void DataAnalysis::loadHumidityData()
{
    m_humidityChart->removeAllSeries();
    foreach(QAbstractAxis* axis, m_humidityChart->axes()) {
        m_humidityChart->removeAxis(axis);
        delete axis;
    }

    auto humidityData = fetchData("humidity");
    QLineSeries *series = new QLineSeries();
    series->setName(m_currentDeviceId == -1 ? "平均湿度" : QString("设备 %1 湿度").arg(m_currentDeviceId));

    for (const auto& point : humidityData) {
        series->append(point.first.toMSecsSinceEpoch(), point.second);
    }

    m_humidityChart->addSeries(series);

    // 设置X轴(时间轴)
    QDateTimeAxis *axisX = new QDateTimeAxis;
    axisX->setFormat("MM-dd hh:mm");
    axisX->setTitleText("时间");
    m_humidityChart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    // 设置Y轴(湿度值)
    QValueAxis *axisY = new QValueAxis;
    axisY->setLabelFormat("%.1f");
    axisY->setTitleText("湿度(%)");
    m_humidityChart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
}

QVector<QPair<QString, int>> DataAnalysis::fetchAlertStats()
{
    QVector<QPair<QString, int>> stats;

    QString sql = QString("SELECT status, COUNT(*) FROM alarm_records WHERE timestamp BETWEEN '%1' AND '%2'")
                 .arg(m_startTime.toString(Qt::ISODate))
                 .arg(m_endTime.toString(Qt::ISODate));

    if (m_currentDeviceId != -1) {
        sql += QString(" AND device_id = %1").arg(m_currentDeviceId);
    }
    sql += " GROUP BY status";

    QString response = dbManager->sendRequest(sql);
    if (response.startsWith("Error:")) {
        qDebug() << "获取告警数据失败:" << response;
        return stats;
    }

    QStringList rows = response.split("\n", QString::SkipEmptyParts);
    foreach (const QString &row, rows) {
        QStringList cols = row.split(" | ", QString::SkipEmptyParts);
        if (cols.size() >= 2) {
            stats.append(qMakePair(cols[0], cols[1].toInt()));
        }
    }

    return stats;
}

void DataAnalysis::loadAlertData()
{
    m_alertChart->removeAllSeries();
    foreach(QAbstractAxis* axis, m_alertChart->axes()) {
        m_alertChart->removeAxis(axis);
        delete axis;
    }

    auto alertStats = fetchAlertStats();
    QBarSeries *series = new QBarSeries();
    QBarSet *processedSet = new QBarSet("已处理");
    QBarSet *unprocessedSet = new QBarSet("未处理");

    int processedCount = 0;
    int unprocessedCount = 0;

    for (const auto& stat : alertStats) {
        if (stat.first == "已处理") {
            processedCount = stat.second;
        } else {
            unprocessedCount = stat.second;
        }
    }

    *processedSet << processedCount;
    *unprocessedSet << unprocessedCount;

    series->append(processedSet);
    series->append(unprocessedSet);
    m_alertChart->addSeries(series);

    // 设置分类轴
    QBarCategoryAxis *axisX = new QBarCategoryAxis();
    axisX->append("告警状态");
    m_alertChart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    // 设置数值轴
    QValueAxis *axisY = new QValueAxis();
    axisY->setTitleText("数量");
    m_alertChart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
}

void DataAnalysis::exportChart()
{
    QString fileName = QFileDialog::getSaveFileName(this, "导出图表", "", "PNG图像 (*.png);;JPEG图像 (*.jpg);;PDF文件 (*.pdf)");
    if(fileName.isEmpty()) return;

    QPixmap pixmap;
    if(fileName.endsWith(".png") || fileName.endsWith(".jpg")) {
        if(ui->tabWidget->currentIndex() == 0) {
            pixmap = ui->temperatureChartView->grab();
        } else if(ui->tabWidget->currentIndex() == 1) {
            pixmap = ui->humidityChartView->grab();
        } else {
            pixmap = ui->alertChartView->grab();
        }
        pixmap.save(fileName);
    } else if(fileName.endsWith(".pdf")) {
        QPrinter printer(QPrinter::HighResolution);
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setOutputFileName(fileName);

        QPainter painter(&printer);
        if(ui->tabWidget->currentIndex() == 0) {
            ui->temperatureChartView->render(&painter);
        } else if(ui->tabWidget->currentIndex() == 1) {
            ui->humidityChartView->render(&painter);
        } else {
            ui->alertChartView->render(&painter);
        }
        painter.end();
    }
}

void DataAnalysis::onAnalyzeButtonClicked()
{
    // 只有当选择了具体设备时才执行分析
    if (m_currentDeviceId != -1) {
        performTrendAnalysis();
    } else {
        QMessageBox::information(this, "提示", "请先选择设备");
    }
}

void DataAnalysis::performTrendAnalysis()
{
    auto temperatureData = fetchData("temperature");
    QVector<double> temperatures;
    for (const auto& point : temperatureData) {
        temperatures.append(point.second);
    }

    // 简单趋势分析
    if (temperatures.size() >= 2) {
        double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
        int n = temperatures.size();

        for (int i = 0; i < n; i++) {
            sumX += i;
            sumY += temperatures[i];
            sumXY += i * temperatures[i];
            sumX2 += i * i;
        }

        double slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);

        QString trend;
        if (slope > 0.1) {
            trend = "上升趋势";
        } else if (slope < -0.1) {
            trend = "下降趋势";
        } else {
            trend = "平稳趋势";
        }

        QString prediction = QString("当前数据趋势: %1 (斜率: %2)").arg(trend).arg(slope, 0, 'f', 2);
        ui->analysisResultLabel->setText(prediction);
    } else {
        ui->analysisResultLabel->setText("数据不足，无法分析趋势");
    }
}
